package com.xnyzc.lhy.finance.service.impl.bill;

import com.xnyzc.lhy.common.entity.Rv;
import com.xnyzc.lhy.common.exception.PangException;
import com.xnyzc.lhy.common.penum.EErrorCode;
import com.xnyzc.lhy.common.penum.order.EBillType;
import com.xnyzc.lhy.common.util.CheckUtil;
import com.xnyzc.lhy.common.util.DateUtil;
import com.xnyzc.lhy.common.util.IDUtil;
import com.xnyzc.lhy.common.util.TokenUtil;
import com.xnyzc.lhy.finance.constant.BillConstant;
import com.xnyzc.lhy.finance.constant.MessageConstant;
import com.xnyzc.lhy.finance.entity.bill.OaDBill;
import com.xnyzc.lhy.finance.mapper.bill.OaDBillMapper;
import com.xnyzc.lhy.finance.params.dto.bill.OaDriverBillDTO;
import com.xnyzc.lhy.finance.params.vo.bill.*;
import com.xnyzc.lhy.finance.params.vo.bill.mapper.OaDriverBillMapperVO;
import com.xnyzc.lhy.finance.service.bill.IOaDBillService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xnyzc.lhy.finance.service.fegin.message.FeignMessageService;
import com.xnyzc.lhy.order.entity.user.message.OaSysMessage;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * <p>
 * 司机账单表 服务实现类
 * </p>
 *
 * @author cuixiaojian
 * @since 2019-10-16
 */
@Slf4j
@Service
public class OaDBillServiceImpl extends ServiceImpl<OaDBillMapper, OaDBill> implements IOaDBillService {

    @Autowired
    private OaDBillMapper oaDBillMapper;

    @Autowired
    private FeignMessageService feignMessageService;

    /**
     * 获取账单类型
     *
     * @param billType 账单类型
     * @return Rv
     */
    @Override
    public Rv getBillType(String billType) {

        if (CheckUtil.objIsNotEmpty(billType)) {
            if (!(billType.equals("0") || billType.equals("1"))) {
                throw PangException.create(EErrorCode.unKnowParams);
            }
        }

        try {
            return Rv.wrap(oaDBillMapper.queryBillType(billType));
        } catch (Exception e) {
            log.error(e.getMessage());
            throw PangException.create(EErrorCode.billTypeErr);
        }
    }

    /**
     * 获取司机账单信息
     *
     * @param oaDriverBillDTO 入参DTO
     * @return List -> data
     */
    @Override
    public Rv getDriverBillDetial(OaDriverBillDTO oaDriverBillDTO) {

        if (
                CheckUtil.objIsEmpty(oaDriverBillDTO.getDriverId())
                        || CheckUtil.objIsEmpty(oaDriverBillDTO.getMonth())
                        || CheckUtil.objIsEmpty(oaDriverBillDTO.getPage())
        ) {
            throw PangException.create(EErrorCode.missingArg);
        }

        if (CheckUtil.objIsEmpty(oaDriverBillDTO.getLimit())) {
            oaDriverBillDTO.setLimit(3L);
        }

        // 查询父级列表
        List<OaDriverBillGroupVO> oaDriverBillGroupVOList = oaDBillMapper.queryDriverBillGroup(oaDriverBillDTO);

        if (CheckUtil.collectionIsNotEmpty(oaDriverBillGroupVOList)) {
            oaDriverBillDTO.setStartDate(oaDriverBillGroupVOList.get(oaDriverBillGroupVOList.size() - 1).getDate());

            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");

            try {
                oaDriverBillDTO.setEndDate(simpleDateFormat.format(DateUtil.dateAddDays(simpleDateFormat.parse(oaDriverBillGroupVOList.get(0).getDate()), 1)));
            } catch (ParseException e) {
                log.error(e.getMessage());
                throw PangException.create(EErrorCode.dataParseError);
            }

            log.info("获取组时间范围：开始时间{},结束时间{}", oaDriverBillDTO.getStartDate(), oaDriverBillDTO.getEndDate());
        } else {
            // 若查询父级列表无结果
            return Rv.wrap(new OaDriverBillVO());
        }

        // 查询子级列表
        List<OaDriverBillMapperVO> oaDriverBillMapperVOList = oaDBillMapper.queryDriverBillDetial(oaDriverBillDTO);

        for (OaDriverBillGroupVO oaDriverBillGroupVO : oaDriverBillGroupVOList) {

            // 设置日收入初始值
            oaDriverBillGroupVO.setDailyAmount("0.00");
            // 创建
            oaDriverBillGroupVO.setElements(new ArrayList<>());
            for (OaDriverBillMapperVO oaDriverBillMapperVO : oaDriverBillMapperVOList) {
                if (oaDriverBillMapperVO.getDate().equals(oaDriverBillGroupVO.getDate())) {

                    // 设置增加父级日总金额
                    if (oaDriverBillMapperVO.getBillType().equals(BillConstant.INCOME)) {
                        oaDriverBillGroupVO.setDailyAmount(new BigDecimal(oaDriverBillGroupVO.getDailyAmount()).add(oaDriverBillMapperVO.getBillAmount()).toString());
                    } else if (oaDriverBillMapperVO.getBillType().equals(BillConstant.EXPEND)) {
                        oaDriverBillGroupVO.setDailyAmount(new BigDecimal(oaDriverBillGroupVO.getDailyAmount()).subtract(oaDriverBillMapperVO.getBillAmount()).toString());
                    }

                    // 添加子级记录
                    OaDriverBillElementVo oaDriverBillElementVo = new OaDriverBillElementVo();
                    oaDriverBillElementVo.setBillId(oaDriverBillMapperVO.getBillId());
                    oaDriverBillElementVo.setAmount(oaDriverBillMapperVO.getBillAmount().toString());
                    oaDriverBillElementVo.setType(oaDriverBillMapperVO.getBillType().toString());
                    oaDriverBillElementVo.setDesc(oaDriverBillMapperVO.getLabel());
                    oaDriverBillElementVo.setTime(oaDriverBillMapperVO.getTime());

                    oaDriverBillGroupVO.getElements().add(oaDriverBillElementVo);

                }
            }

        }

        for (OaDriverBillGroupVO oaDriverBillGroupVO : oaDriverBillGroupVOList) {
            if (oaDriverBillGroupVO.getDate().equals(DateUtil.getStringDateShort(new Date()))) {
                oaDriverBillGroupVO.setDate("今天");
            } else if (oaDriverBillGroupVO.getDate().equals(DateUtil.getStringDateShortUp(new Date()))) {
                oaDriverBillGroupVO.setDate("昨天");
            } else {
                oaDriverBillGroupVO.setDate(oaDriverBillGroupVO.getDate().replace("-", "."));
            }

            if (new BigDecimal(oaDriverBillGroupVO.getDailyAmount()).compareTo(BigDecimal.valueOf(0.00)) == 1) {
                oaDriverBillGroupVO.setDailyAmount("+" + oaDriverBillGroupVO.getDailyAmount());
            }

        }

        // 查询收入和支出
        OaDriverBillVO oaDriverBillVO = oaDBillMapper.queryIncomeAndExpend(oaDriverBillDTO);

        if (CheckUtil.objIsEmpty(oaDriverBillVO)) {
            oaDriverBillVO = new OaDriverBillVO();
            oaDriverBillVO.setIncome("0.00");
            // 需求变更：删除支出汇总(依然保留查询code)
            oaDriverBillVO.setExpend("0.00");
        } else {

            if (CheckUtil.objIsEmpty(oaDriverBillVO.getIncome())) {
                oaDriverBillVO.setIncome("0.00");
            }
            if (CheckUtil.objIsEmpty(oaDriverBillVO.getExpend())) {
                oaDriverBillVO.setExpend("0.00");
            }

        }


        log.info("司机的收入和支出为{},{}", oaDriverBillVO.getIncome(), oaDriverBillVO.getExpend());

        // 设置组集合
        oaDriverBillVO.setGroups(oaDriverBillGroupVOList);

        return Rv.wrap(oaDriverBillVO);
    }

    /**
     * 获取账单详情
     *
     * @param billId 账单ID
     * @return Object
     */
    @Override
    public Rv getDriverBillInfo(Long billId) {

        if (CheckUtil.objIsEmpty(billId)) {
            throw PangException.create(EErrorCode.missingArg);
        }

        OaDBill oaDBill = oaDBillMapper.queryDriverBillInfo(billId);

        if (CheckUtil.objIsEmpty(oaDBill)) {
            throw PangException.create(EErrorCode.unBillInfo);
        }

        // 将检索结果转换为list响应给前端
        OaDriverBillInfoVO oaDriverBillInfoVO = new OaDriverBillInfoVO();
        // 设置金额
        oaDriverBillInfoVO.setAmount(oaDBill.getBillAmount().toString());
        // 设置收支类型
        oaDriverBillInfoVO.setBillType(oaDBill.getBillType().toString());

        // 判断如果不为空则添加进集合
        List<OaDriverInfoFiledVO> oaDriverBillInfoFiledVOList = new ArrayList<>();

        if (CheckUtil.objIsNotEmpty(oaDBill.getBillTypeLabel())) {
            OaDriverInfoFiledVO oaDriverBillInfoFiledVO = new OaDriverInfoFiledVO();
            oaDriverBillInfoFiledVO.setDescText("收入类型");
            oaDriverBillInfoFiledVO.setValue(oaDBill.getBillTypeLabel());
            oaDriverBillInfoFiledVOList.add(oaDriverBillInfoFiledVO);
            oaDriverBillInfoFiledVO = null;
        }
        if (CheckUtil.objIsNotEmpty(oaDBill.getLogonTagLabel())) {
            OaDriverInfoFiledVO oaDriverBillInfoFiledVO = new OaDriverInfoFiledVO();
            oaDriverBillInfoFiledVO.setDescText("收入账户");
            oaDriverBillInfoFiledVO.setValue(oaDBill.getLogonTagLabel());
            oaDriverBillInfoFiledVOList.add(oaDriverBillInfoFiledVO);
            oaDriverBillInfoFiledVO = null;
        }
        if (CheckUtil.objIsNotEmpty(oaDBill.getCreateTime())) {
            OaDriverInfoFiledVO oaDriverBillInfoFiledVO = new OaDriverInfoFiledVO();
            oaDriverBillInfoFiledVO.setDescText("创建时间");
            oaDriverBillInfoFiledVO.setValue(DateUtil.convertDateToString(oaDBill.getCreateTime()));
            oaDriverBillInfoFiledVOList.add(oaDriverBillInfoFiledVO);
            oaDriverBillInfoFiledVO = null;
        }
        if (CheckUtil.objIsNotEmpty(oaDBill.getOrderNumber())) {
            OaDriverInfoFiledVO oaDriverBillInfoFiledVO = new OaDriverInfoFiledVO();
            oaDriverBillInfoFiledVO.setDescText("关联行程编号");
            oaDriverBillInfoFiledVO.setValue(oaDBill.getOrderNumber());
            oaDriverBillInfoFiledVOList.add(oaDriverBillInfoFiledVO);
            oaDriverBillInfoFiledVO = null;
        }
        if (CheckUtil.objIsNotEmpty(oaDBill.getBillNumber())) {
            OaDriverInfoFiledVO oaDriverBillInfoFiledVO = new OaDriverInfoFiledVO();
            oaDriverBillInfoFiledVO.setDescText("交易流水号");
            oaDriverBillInfoFiledVO.setValue(oaDBill.getBillNumber());
            oaDriverBillInfoFiledVOList.add(oaDriverBillInfoFiledVO);
            oaDriverBillInfoFiledVO = null;
        }

        oaDriverBillInfoVO.setOrderNo(oaDBill.getOrderNumber());
        oaDriverBillInfoVO.setOaDriverBillInfoVOList(oaDriverBillInfoFiledVOList);

        // 提醒清除临时对象
        System.gc();

        return Rv.wrap(oaDriverBillInfoVO);
    }

    /**
     * 保存账单信息
     *
     * @param oaDBill 账单实体
     * @return Map
     */
    @Override
    public Rv saveDriverBill(OaDBill oaDBill) {
        log.info("-------- 开始保存账单 --------");
        if (CheckUtil.objIsEmpty(oaDBill)) {
            throw PangException.create(EErrorCode.missingArg);
        }

        if (CheckUtil.objIsEmpty(oaDBill.getDriverId())) {
            oaDBill.setDriverId(TokenUtil.getTokenUserId());
        }

        if (
                CheckUtil.objIsEmpty(oaDBill.getBillAmount()) ||
                        CheckUtil.objIsEmpty(oaDBill.getBillType()) ||
                        CheckUtil.objIsEmpty(oaDBill.getBillTypeDesc()) ||
                        CheckUtil.objIsEmpty(oaDBill.getLogonTag())
        ) {
            log.error(oaDBill.toString());
            throw PangException.create(EErrorCode.missingArg);
        }

        Date date = new Date();
        Long id = IDUtil.nextId();

        oaDBill.setBillId(id);

        if (CheckUtil.objIsNotEmpty(TokenUtil.getTag())) {
            oaDBill.setTag(TokenUtil.getTag());
        }

        oaDBill.setBillNumber(BillConstant.FIX + id);
        oaDBill.setCreateUser(oaDBill.getDriverId());
        oaDBill.setCreateTime(date);
        oaDBill.setUpdateUser(oaDBill.getDriverId());
        oaDBill.setUpdateTime(date);
        Integer result = oaDBillMapper.insert(oaDBill);
        log.info("-------- 结束保存账单 --------");
        Map<String, Object> resultMap = new HashMap<>(1);
        resultMap.put("isSuccess", result.toString());

        log.info("-------- 开始组织消息内容 --------");
        // 发送消息
        OaSysMessage oaSysMessage = new OaSysMessage();
        log.info("当前消息类型 ---->>>>>> {}", oaDBill.getBillTypeDesc());
        if (oaDBill.getBillTypeDesc().equals(EBillType.ITINERARY_FARE.getKey())) {
            // 行程车费 消息
            oaSysMessage.setMessageType(2);
            oaSysMessage.setPushCode(EBillType.ITINERARY_FARE.getIdenifition());
            oaSysMessage.setMessageContent(MessageConstant.BILL_MESSAGE_FIX + oaDBill.getBillAmount() + MessageConstant.BILL_MESSAGE_PRE);
        } else if (oaDBill.getBillTypeDesc().equals(EBillType.CASH_WITHDRAWALS.getKey())) {
            // 提现支出 消息
            Integer index = MessageConstant.CASH_WITHDRAWAL_EXPENDITURE.indexOf("%");
            oaSysMessage.setPushCode(EBillType.CASH_WITHDRAWALS.getIdenifition());
            StringBuffer stringBuffer = new StringBuffer(MessageConstant.CASH_WITHDRAWAL_EXPENDITURE);
            stringBuffer.replace(index, index + 1, oaDBill.getBillAmount().toString());
            oaSysMessage.setMessageContent(stringBuffer.toString());
            oaSysMessage.setMessageType(2);
        }

        oaSysMessage.setDriverId(oaDBill.getDriverId());
        oaSysMessage.setTag(oaDBill.getTag());
        log.info("调用order服务保存消息, 当前消息内容: {}", oaSysMessage);
        feignMessageService.saveMessage(oaSysMessage);

        return Rv.wrap(resultMap);

    }

}
